#include "credit_state.h"
#include "gameflow/game_flow_manager.h"
#include "ui/ui_widget.h"
#include "script/scripthelper.h"

#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#include <cassert>
using namespace LuaPlus;
using namespace script;

const float	CreditState::COUNTDOWN_TIME = 18.0f;
CreditState::CreditState(	camera::FbCamera*	pCamera ) :
	gameflow::UIState(pCamera, "ui/credits.ui", ""),
	m_CurrentIndex(0),
	m_Range(0, 1)
{
}

CreditState::~CreditState()
{

}

bool		CreditState::OnEnter()
{
	m_CurrentIndex = 0;
	gameflow::UIState::OnEnter();

	for (int i=0; i<ENTRY_C; i++)
	{
		m_EntryA[i].pWidget = NULL;
		m_EntryA[i].Countdown.SetLimit(COUNTDOWN_TIME);
	}

	m_Text.resize(0);
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	if (!ScriptHelper::DoFile(*pScript, "scripts/credits.lua"))
	{
		_LOG(MSG_ERROR, "Unable to load Credits !");
		 LuaState::Destroy( pScript );
		return false;
	}
	// fix RAII bug
	{
		LuaPlus::LuaObject	Credits = ScriptHelper::GetObj(*pScript, "CREDITS");
		if (Credits.IsTable())
		{
			for (int i=0; i<Credits.GetCount(); i++)
			{
				TextEntry	NewEntry;
				if (Credits.GetByIndex(i+1).GetString())
				{
					NewEntry.Text			= Credits.GetByIndex(i+1).GetString();
					if (NewEntry.Text[0]=='*')
					{
						NewEntry.Header = true;
						NewEntry.Text = NewEntry.Text.substr(1, NewEntry.Text.size());
					} else
					{
						NewEntry.Header = false;
					}
				}
				m_Text.push_back(NewEntry);
			}
		}
	}
	LuaState::Destroy( pScript );


	if (m_Panels.empty()) return false;	// no valid panel
	ui::UIWidget*	pPanel = m_Panels[0];
	assert(pPanel);

	for (int i=0; i<ENTRY_C; i++)
	{
		char		Buffer[256];
		sprintf(Buffer, "Credits%i", i);
		m_EntryA[i].pWidget = pPanel->GetWidgetByName(Buffer);
		m_EntryA[i].Countdown.SetLimit(COUNTDOWN_TIME);
		float	Progress= i * (1.0f / (float)ENTRY_C);
		m_EntryA[i].Countdown.SetCounter(COUNTDOWN_TIME * Progress);
		if (m_EntryA[i].pWidget)
		{
			m_EntryA[i].pWidget->SetPosition(math::Vec2(0,1));
			FillEntry(i);
		}
	}

	return true;
}

bool		CreditState::OnExit()
{
	gameflow::UIState::OnExit();
	m_CurrentIndex = 0;
	return true;
}

void	CreditState::FillEntry(int index)
{
	// update text or sumthing
	if (m_EntryA[index].pWidget)
	{
		if (m_CurrentIndex < (int)m_Text.size())
		{
			m_EntryA[index].pWidget->SetTextA(m_Text[m_CurrentIndex].Text);
			if (m_Text[m_CurrentIndex].Header)
			{
				m_EntryA[index].pWidget->SetTextColor(1.0f,0.5f,0.0f,1.0f);
			} else
			{
				m_EntryA[index].pWidget->SetTextColor(1, 1, 1, 1);
			}
			m_CurrentIndex ++;
			if (m_CurrentIndex>=(int)m_Text.size())
			{
				m_CurrentIndex = 0;
			}
		}
	}
}

bool		CreditState::Tick(float dt)
{
	gameflow::UIState::Tick(dt);

	for (int i=0; i<ENTRY_C; i++)
	{
		if (m_EntryA[i].pWidget)
		{
			m_EntryA[i].Countdown.Tick(dt);
			if (m_EntryA[i].Countdown.IsReady())
			{
				m_EntryA[i].Countdown.Reset();
				FillEntry(i);
			}
			math::Vec2	Pos = m_EntryA[i].pWidget->GetPosition();
			Pos.y = m_Range.y + (m_EntryA[i].Countdown.GetProgress() * (m_Range.x-m_Range.y));
			m_EntryA[i].pWidget->SetPosition(Pos);

		}
	}
	
	return true;
}

bool		CreditState::PostRender()
{
	return true;
}


void	CreditState::OnMOGAKeyDownEvent(int	KeyCode)
{
	switch( (input::MOGAJoystick::KEYCODE)KeyCode)
	{
		case input::MOGAJoystick::KEYCODE_BUTTON_B:				
			gameflow::GameState* pPreviousState = gameflow::GameFlowManager::Instance().GetPreviousState();
			if(pPreviousState)
			{				
				gameflow::GameFlowManager::Instance().SetTransitionEffect("fade",pPreviousState->GetName().c_str(),"",NULL);
			}
		break;
	}
}